/*
 * jsTree 0.9
 * http://code.google.com/p/jslist
 *
 * Copyright (c) 2011 CMS XLBS
 *
 * Licensed under Apache License
 * http://www.apache.org/licenses/
 *
 */
(function( $ ){

	/**
	 * return the jquery object (or the result returned from an executable-method call)
	 */
	$.fn.jslist = function(options) {
		var args = Array.prototype.slice.call(arguments,1) , result = this;

		if (typeof options == 'string') { // call method $(...).jslist("showMore") or call property $(...).jslist("data")
			this.each(function() {
				var current_instance = $.data(this, "_jslist_instance");
				// call the method if the target is a function,otherwise return the target
				var returnValue = (current_instance && $.isFunction(current_instance[options])) ? current_instance[options].apply(current_instance, args) : current_instance;
				(options.indexOf("get") != 0 ) || (result = returnValue); 
			});
		}
		else {
			var _options = options ? $.extend({}, options) : {};
			_options.plugins = $.isArray(_options.plugins) ? _options.plugins : $.jslist.defaults.plugins.slice();
			_options.plugins.unshift("core");

			this.each(function() { // dom element iterator
				var instance_options = $.extend(true, {}, $.jslist.defaults, _options),// extend global default options with call arguments
				    current_instance = $.data(this, "_jslist_instance"),
					$this = $(this); // dom element reference => jquery object reference
				current_instance || (current_instance = new $.jslist._instance($this, instance_options)); 
				$.data(this, "_jslist_instance", current_instance);
				// init all specfied plugins for this instance
				$.each(current_instance.get_options().plugins, 
						function (i, val) {
							$.extend(true,current_instance.data,(instance_options[val] ? instance_options[val] : {})); 
						});
				$.each(current_instance.get_options().plugins, 
						function (i, val) { 
							if($.jslist._plugins[val]) { 
								$.jslist._plugins[val]._init.apply(current_instance); 
							}
						});
			});
		}
		
		return result;
	};

	// jslist global repository
	$.jslist = {
		defaults : {
			plugins : []
		},
		_instance : function (container, options) { //the container is a jquery object (dom element wrappered)
			this.init = $.noop;
			this.destroy = $.noop;
			this.data = { }; // merged plugin options
			this.get_options	= function () { return $.extend(true, {}, options); }; // return options copy
			this.get_container	= function () { return container; };
		},
		_fn : {
			//can be accessed by this.xxx within instance execution context
			}, 
		_plugins : {
			//plugins repository,to access by plugin-name:_plugins["core"]
			},
		plugin : function (pluginName, pluginBody) {
			pluginBody = $.extend(
				{
					_init		: $.noop, 
					_destroy	: $.noop,
					_fn			: {}
				}, pluginBody);
			$.jslist._plugins[pluginName] = pluginBody;
			$.jslist.defaults[pluginName] = pluginBody.defaults;
			$.each(pluginBody._fn, function (fnName, fnBody) {
				$.jslist._fn[fnName] = function () {
					return fnBody.apply(this, arguments);  //Here,"this" refer to the jslist instance
				};
				$.jslist._fn[fnName]._pluginName = pluginName;
			});
		}
	};
	
	$.jslist._fn = $.jslist._instance.prototype = {};
	
})( jQuery );

(function ($) {
	$.jslist.plugin("core",{
		_init: function() {
			//init the table head
			if (this.get_container().find("table").size() == 0) {
				$("<table class='table table-striped cms-table'><thead></thead><tbody></tbody></table>").appendTo(this.get_container());
			}; 

			var trRef = $("<tr></tr>");
			var indexTdRef = this.data.createIndexColumnHead.call(this);
			(indexTdRef == null) || indexTdRef.appendTo(trRef);
			$.each(this.data.columnMetadatas, function(i,val){
	 			$("<th></th>").attr("width",val.width).text(val.title).appendTo(trRef);
			});
			
			if (this.data.utilColumnEnabled) {
				var utilTdRef = this.data.createUtilColumnHead.call(this);
				(utilTdRef == null) || utilTdRef.appendTo(trRef);
				trRef.appendTo(this.get_container().find("thead"));
			}
			
			//init the more bar
			$("<div class='well cms_more'><a href='javascript:;'><i class='icon-arrow-down'></i>查看更多...</a></div>")
			.delegate("a","click",$.proxy(function() {
				this.get_container().triggerHandler(new $.Event("list_more.jslist"));
			},this))
			.insertAfter(this.get_container().find("table"));
			
			//bind event handler
			this.get_container().bind("list_more.jslist",$.proxy(function(event,data) {
				this.listMore();
			},this));
			
			this.get_container().bind("clear_all.jslist",$.proxy(function(event,data) {
				this.get_container().find("tbody,div.page-header small").html("");
			},this));

			this.get_container().bind("list_count_retrieved.jslist",$.proxy(function(event,data) {
				if (data.retrievedCount >= data.totalCount) {
					this.get_container().find(".cms_more").hide();
				}
				else {
					this.get_container().find(".cms_more").show();
				}
				
				this.get_container().find("div.page-header small").html("("+data.retrievedCount+"/"+data.totalCount+"条)"); 
			},this));

			this.get_container().bind("list_retrieved.jslist",$.proxy(function(event,data) {
				var tbodyRef = this.get_container().find("tbody");
				var _this = this;
				$.each(data.data,function(i, item) {
					var trRef = $("<tr></tr>").attr("id","tr_"+item.id);
					var indexTdRef = _this.data.createIndexColumn.call(_this,_this.data.status.retrievedCount+i,item);
					if (indexTdRef != null) {
						indexTdRef.appendTo(trRef);
					}
					$.each(_this.data.columnMetadatas, function(i,val){
						if (val.render != null) {
							$("<td></td>").html(val.render.apply(item)).appendTo(trRef);
						}
						else {
							if (val["showDetail"]) {
								$("<td><a href='javascript:;'>"+item[val.name]+"</a></td>").delegate("a","click",$.proxy(function() {
									window.location.href = this.data.detailUrl+"?id="+item["id"];
								},_this)).appendTo(trRef);
							}
							else {
								var tdTemp = $("<td></td>"),tdVal = item[val.name];
								if (val.maxLength > 0) {
									if (tdVal != null) {
										tdTemp.attr("title",tdVal);
									}
									tdTemp.html((tdVal != null)? (""+tdVal).slice(0,val.maxLength)+" ...":"");
								}
								else {
									tdTemp.html(tdVal);
								}
								tdTemp.appendTo(trRef);
							}
						}
					});

					if (_this.data.utilColumnEnabled) {
						var utilTdRef = _this.data.createUtilColumn.call(_this,i,item);
						(utilTdRef == null) || _this.data.afterCreateUtilColumn.call(_this,i,item,utilTdRef);
						(utilTdRef == null) || utilTdRef.appendTo(trRef);
					}
					
					trRef.appendTo(tbodyRef);
				});

				this.data.status.retrievedCount += data.data.length;
				this.get_container().triggerHandler(new $.Event("list_count_retrieved.jslist"),  
													{retrievedCount:this.data.status.retrievedCount,
													totalCount:this.data.status.totalCount});
			},this));
		},
		defaults: {
			status: {
		    	start:0,
				limit:20,
				retrievedCount:0,
				totalCount:0
			},
			queryParams: {},
			countUrl:"count.json",
			listUrl:"list.json",
			detailUrl:"detail.do",
			utilColumnEnabled:false,
			createIndexColumnHead:function() { return $("<th width='30'></th>") },
			createIndexColumn:function(i,item) { return $("<td>"+(i+1)+"</td>");}, //return a jquery object wrapped the dom element inside
			createUtilColumnHead:function() {return $("<th width='70'>操作</th>");},
			createUtilColumn:function(i,item) {return $("<td></td>");},   //return a jquery object wrapped the dom element inside
			afterCreateUtilColumn:function(i,item,utilColumnRef) {;} // invoke after create util column, user can do post-processor on the util column
		},
		_fn: { 
			refresh : function( ) {
				this.get_container().triggerHandler(new $.Event("clear_all.jslist"));
			
				$.extend(this.data.status,{
			    	start:0,
					limit:20,
					retrievedCount:0,
					totalCount:0
				});

		    	this.listCount();
		    	this.listMore();
		    },
		    listMore : function( ) { 
		    	if (this.data.status.retrievedCount  > 0  && this.data.status.retrievedCount >= this.data.status.totalCount) {
					return;
				}

		    	var ajaxDataParam = $.extend({},{
					"start":this.data.status.start++,
					"limit":this.data.status.limit
				},this.data.queryParams),
		    		_this = this;
		    	
				$.ajax({
					type: "GET",
					url: this.data.listUrl,
					dataType: "json",
					data: ajaxDataParam,
					success:function(json) {
						if (!json.succeed) {
							$.alert(json.message);
							return;
						} 
						
						_this.get_container().triggerHandler(new $.Event("list_retrieved.jslist"), {data:json.data});
					},
					error: function(message) {
						$.alert(message);
					}
				});
		    },
		    listCount : function( content ) {
		    	var ajaxDataParam = $.extend({},this.data.queryParams),
		    		_this = this;
		    	
		    	$.ajax({
			    	type: "GET",
			    	url: this.data.countUrl,
			    	data: ajaxDataParam,
			    	dataType:"json",
			    	success:function(json) {
			    		if (!json.succeed) {
			    			$.alert(json.message);
			    			return;
			    		}

			    		_this.data.status.totalCount = json.data;
			    		_this.get_container().triggerHandler(new $.Event("list_count_retrieved.jslist"),  
															{retrievedCount:_this.data.status.retrievedCount,
															totalCount:_this.data.status.totalCount});			    	
			    	},
					error: function(message) {
						$.alert(message);
					}
		    	});
		    }
		}
	});
})( jQuery );

(function ($) {
	$.jslist.plugin("title",{
		_init: function() {
			//init the page header
			var titleStyle = "class='page-header'";
			if (this.data.titleType == "gridHeader") {
				titleStyle = "";
			}
			$("<div "+titleStyle+"><h2>"+this.data.title+"<small></small></h2><div class='cms_toolbar'><ul></ul></div></div>").prependTo(this.get_container());
			
			//initialize the buttons
			var _this = this;
			$.each(this.data.buttons,function(i,item) {
				var randomId = "btn_" + ((Math.random() * 0x10000) | 0);
				var buttonBody = $(item.script).attr("id",randomId);
				
				var pageHeader = _this.get_container().find("div.cms_toolbar ul").prepend($("<li></li>").append(buttonBody));
				$.each(item.eventHandler,function(pn,pv) {
					pageHeader.delegate("#"+randomId,pn,$.proxy(pv,_this));
				});
			});
		},
		defaults: {
			titleType:"pageHeader",// pageHeader|gridHeader
			buttons: []
		},
		_fn: {
		}
	});
})( jQuery );

(function ($) {
	$.jslist.plugin("filter",{
		_init: function() {
			var _this = this;
			$("<li><input class='input-medium search-query' type='text'><a id='_list_filter_action' href='javascript:;' class='btn' ><i class='icon-ok'></i>查询</a></li>")
			.delegate("#_list_filter_action","click",$.proxy(function() {
				this.get_container().triggerHandler(new $.Event("list_filter.jslist"));
			},this))
			.appendTo(this.get_container().find("div.cms_toolbar ul"));
			
			this.get_container().bind("list_filter.jslist",$.proxy(function() {
				this.listByFilter();
			},this))
		},
		defaults: {
		},
		_fn: {
			listByFilter : function() {
				this.data.queryParams.name = this.get_container().find("div.cms_toolbar input:text").val();
				this.refresh();
			}
		}
	});
})( jQuery );

(function ($) {
	$.jslist.plugin("cud",{
		_init: function() {
			if (this.data.createActionEnabled) {
				$("<li><a id='_create_item_action' href='javascript:;' class='btn'><i class='icon-plus'></i>新增</a></li>")
				.delegate("#_create_item_action","click",$.proxy(function() {
					this.get_container().triggerHandler(new $.Event("create_item.jslist"));
				},this))
				.prependTo(this.get_container().find("div.cms_toolbar ul"));
			}
			this.get_container().bind("create_item.jslist",$.proxy(function(event) {
				window.location.href = this.data.newUrl;
			},this));
			this.get_container().bind("modify_item.jslist",$.proxy(function(event,data) {
				window.location.href = this.data.editUrl+"?id="+data.id;
			},this));
			this.get_container().bind("delete_item.jslist",$.proxy(function(event,data) {
				if (!this.data.canDelete()) {
					return;
				}
				this.deleteItem(data.id);
			},this));
			this.get_container().bind("delete_item_succeed.jslist",$.proxy(function(event,data) {
				this.get_container().find("#tr_"+data.id).remove();
				$.info("删除成功");
			},this));
		},
		defaults: {
			createActionEnabled:true,
			editActionEnabled:true,
			deleteActionEnabled:true,
			editActionEnabledFunc:null,
			deleteActionEnabledFunc:null,
			newUrl:"edit.do",
			editUrl:"edit.do",
			deleteUrl:"delete.json",
			canDelete:function() {
					return confirm('是否删除？\n请确认是否继续操作 ！')
				},
			utilColumnEnabled:true,
			afterCreateUtilColumn:function(i,item,utilColumnRef) {
				var editActionEnabled = this.data.editActionEnabled;
				if (this.data.editActionEnabledFunc != null) {
					editActionEnabled = this.data.editActionEnabledFunc.call(this,item);
				}
				if (editActionEnabled) {
					var editAction = $("<a href='javascript:;'>修改</a>").bind("click",$.proxy(function() {
						this.get_container().triggerHandler(new $.Event("modify_item.jslist"),{"id":item.id});
					},this));
					utilColumnRef.append(editAction);
				}
				
				utilColumnRef.append("<span> </span>");
				
				var deleteActionEnabled = this.data.deleteActionEnabled;
				if (this.data.deleteActionEnabledFunc != null) {
					deleteActionEnabled = this.data.deleteActionEnabledFunc.call(this,item);
				}
				if (deleteActionEnabled) {
					var deleteAction = $("<a href='javascript:;'>删除</a>").bind("click",$.proxy(function() {
						this.get_container().triggerHandler(new $.Event("delete_item.jslist"),{"id":item.id});
					},this));
					utilColumnRef.append(deleteAction);
				}
			}
		},
		_fn: {
			deleteItem:function(id) {
				var _this = this;
				$.ajax({
					type: "POST",
					url: this.data.deleteUrl,
					data: {"id":id},
					dataType: "json",
					success: function(json){
						if (!json.succeed) {
							$.alert(json.message);
							return;
						}
						
						_this.get_container().triggerHandler(new $.Event("delete_item_succeed.jslist"),{"id":id});
					},
					error:function(message){
						$.alert(message);
					}
				});
			}
		}
	});
})( jQuery );

(function ($) {
	$.jslist.plugin("selectable",{
		_init: function() {
		},
		defaults: {
			selectType: "radio", //radio checkbox is allowed
			createIndexColumnHead:function() {
				if ("checkbox" == this.data.selectType) {
					return $("<th width='30'><input type='checkbox'/></th>").delegate(":checkbox","click",$.proxy(function(event) {
						this.get_container().find(":checkbox").attr("checked",$(event.target).attr("checked")?true:false);
					},this));
				}
				else {
					return $("<th width='30'></th>");
				}
			},
			createIndexColumn:function(i,item) {
				if ("radio" == this.data.selectType) {
					return $("<td></td>").append($("<input type='radio' name='_queryId' value="+item.id+">").data("data",item));
				}
				else if ("checkbox" == this.data.selectType) {
					return $("<td></td>").append($("<input type='checkbox' value='"+item.id+"'>").data("data",item));
				}
				else {
					return $("<td>"+(i+1)+"</td>");
				}
			}
		},
		_fn: {
			getSelectedItems:function() {
				if ("radio" == this.data.selectType) {
					return this.get_container().find("input:radio:checked").data("data");
				}
				else if ("checkbox" == this.data.selectType) {
					return this.get_container().find("input:checkbox:checked").map(function() {
						return $(this).data("data");
					}).get();
				}
				return [];
			}
		}
	});
})( jQuery );

(function ($) {
	$.jslist.plugin("map",{
		_init: function() {
			this.get_container().bind("show_map.jslist",$.proxy(function(event,data) {
				window.showModalDialog(this.data.showMapUrl+"?id="+data.id,data, 
					"dialogWidth:600px; dialogHeight:480px; center:yes");
			},this));
		},
		defaults: {
			showMapUrl:"",
			utilColumnEnabled:true,
			afterCreateUtilColumn:function(i,item,utilColumnRef) {
				var showMapAction = $("<a href='javascript:;'>查看地图</a>").bind("click",$.proxy(function() {
					this.get_container().triggerHandler(new $.Event("show_map.jslist"),{"id":item.id});
				},this));
				utilColumnRef.append(showMapAction);
				showMapAction.appendTo(utilColumnRef);
			}
		},
		_fn: {
		}
	});
})( jQuery );
